package com.fuatnow.game.manager;

import com.fuatnow.game.entity.JsonMessage;
import com.fuatnow.game.entity.User;
import com.fuatnow.game.handler.GateMineSweepConnectionHandler;
import com.fuatnow.game.handler.LoginHandler;
import com.fuatnow.game.handler.MsgHander;
import com.fuatnow.game.handler.RCPHandler;
import com.fuatnow.game.work.Worker;
import io.netty.channel.ChannelHandlerContext;
import org.json.JSONException;
import org.json.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

import static com.fuatnow.game.constant.ProtocolConstant.*;

/**
 * Created by fuatnow on 17/1/10.
 */
public class MessageManager
{
    private static final Logger logger = LoggerFactory.getLogger(MessageManager.class);
    private static MessageManager instance;
    private static Lock lock = new ReentrantLock();
    public static MessageManager getInstance(){
        if(instance == null){
            lock.lock();
            if(instance == null){
                instance = new MessageManager();
            }
            lock.unlock();
            lock = null;
        }
        return instance;
    }

    public void processMessage(ChannelHandlerContext ctx , String msg )
    {
        try
        {
            JSONObject jo = new JSONObject(msg);
            int cmdID = jo.getInt("cmdID");
            MsgHander handle = null;
            switch (cmdID)
            {
                case USER_LOGIN:
                    handle = new LoginHandler(ctx,msg);
                    break;
                case ENTER_MINESWEEP:
                    enterGame(ENTER_MINESWEEP,ctx);
                    break;
                case RCP:
                    handle = nodeToClientMsg(jo);
                    break;
                case BACK_HALL:
                    handle = backHall(jo);
                    break;
                default:
                    handle = clientToNodeMsg(ctx,jo);
                    break;
            }
            Worker.dispath(handle);
        }
        catch (JSONException e)
        {
            System.out.print(e.getStackTrace());
        }
    }

    private void enterGame(int gameType, ChannelHandlerContext ctx)
    {
        ClientConnection client = ClientConnectManager.getInstance().getClientConnection(ctx);
        if(client == null) return;

        if(gameType == ENTER_MINESWEEP)
        {
            client.setNodeCtx(GateMineSweepConnectionHandler.getGateMineSweepConnection());
        }

        if(client.getNodeCtx() != null)
        {
            User usr = client.getUser();
            JsonMessage js = new JsonMessage(ENTER_MINESWEEP);
            js.put("usrName",usr.getUsrName());
            js.put("usrID",usr.getUsrID());
            js.put("headUrl",usr.getPhotoUrl());
            js.put("netID",client.getNetID());
            js.put("errorCode",0);
            String jsStr = js.toString();
            client.getNodeCtx().writeAndFlush(jsStr);
        }
    }

    private  RCPHandler nodeToClientMsg(JSONObject jo)
    {
        int netID = jo.getInt("netID");
        ClientConnection client = ClientConnectManager.getInstance().getClientConnection(netID);
        if(client != null)
        {
            ChannelHandlerContext clientCtx = client.getCtx();
            JSONObject rcpJo = jo.getJSONObject("rcpMsg");
            return new RCPHandler(clientCtx, rcpJo.toString());
        }
        return  null;
    }

    private RCPHandler clientToNodeMsg(ChannelHandlerContext ctx, JSONObject jo)
    {
        ClientConnection client = ClientConnectManager.getInstance().getClientConnection(ctx);
        if(client != null)
        {
            //远程调用node服务
            if(client.getNodeCtx() != null)
            {
                JSONObject joData = null;
                if(jo.has("data") == false)
                {
                    joData = new JSONObject();
                    jo.put("data",joData);
                }
                else
                {
                    joData = jo.getJSONObject("data");
                }
                joData.put("netID",client.getNetID());
                RCPHandler handler =  new RCPHandler(client.getNodeCtx(), jo.toString());
                handler.setNodeToClient(false);
                return handler;
            }
        }
        return  null;
    }

    private  RCPHandler backHall(JSONObject jo)
    {
        int netID = jo.getInt("netID");
        ClientConnection client = ClientConnectManager.getInstance().getClientConnection(netID);
        if(client != null)
        {
            JSONObject rcpJo = jo.getJSONObject("rcpMsg");
            User user = client.getUser();
            JSONObject hallInfo = HallManager.getInstance().getHallInfo(client.getUser());
            rcpJo.getJSONObject("data").put("hallInfo",hallInfo);
            RCPHandler handler =  new RCPHandler(client.getCtx(), rcpJo.toString());
            return handler;
        }
        return  null;
    }
}
